package doan.chuyennganh.util;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;

import jxl.CellView;
import jxl.Workbook;
import jxl.WorkbookSettings;
import jxl.format.UnderlineStyle;
import jxl.write.Label;
import jxl.write.Number;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;
import doan.chuyennganh.model.Attendance;
import doan.chuyennganh.model.AttendanceList;
import doan.chuyennganh.model.Student;

public class WriteExcel {

	private WritableCellFormat timesBoldUnderline;
	private WritableCellFormat times;
	private String outputFile;
	private int column = 0;

	public void setOutputFile(String outputFile) {
		this.outputFile = outputFile;
	}

	public WriteExcel(String outputFile) {
		this.outputFile = outputFile;
	}

	public void write(Collection<? extends Object> students,
			AttendanceList attendancesList, OnFinishedWrittingListener mListener)
			throws IOException, WriteException {
		File file = new File(outputFile);
		WorkbookSettings wbSettings = new WorkbookSettings();
		
		wbSettings.setEncoding("UTF-8");

		//wbSettings.setLocale(new Locale("en", "EN"));

		WritableWorkbook workbook = Workbook.createWorkbook(file, wbSettings);
		workbook.createSheet("Report", 0);
		WritableSheet excelSheet = workbook.getSheet(0);

		if (students == null || students.isEmpty())
			return;
		int i = 0;
		Object object = new Object();
		for (Object obj : students) {
			if (i == 1)
				break;
			object = obj;
			i++;
		}
		Field[] attributes = object.getClass().getDeclaredFields();
		ArrayList<String> columns = new ArrayList<String>();
		for (Field field : attributes) {
			columns.add(field.getName());
		}

		if (attendancesList != null) {
			for (int j = 0; j < attendancesList.size(); j++) {
				columns.add(attendancesList.get(j).getDate());
			}

		}
		createLabel(excelSheet, columns);
		createContentRow(excelSheet, students);
		if (attendancesList != null) {
			for (int j = 0; j < attendancesList.size(); j++) {
				createContentColumn(excelSheet, students, attendancesList.get(j));
			}
		}
		workbook.write();
		workbook.close();
		if (mListener != null) {
			mListener.OnFinished();
		}
	}

	private void createLabel(WritableSheet sheet, ArrayList<String> columns)
			throws WriteException {
		// Lets create a times font
		WritableFont times10pt = new WritableFont(WritableFont.TIMES, 10);
		// Define the cell format
		times = new WritableCellFormat(times10pt);
		// Lets automatically wrap the cells
		times.setWrap(true);

		// create create a bold font with unterlines
		WritableFont times10ptBoldUnderline = new WritableFont(
				WritableFont.TIMES, 10, WritableFont.BOLD, false,
				UnderlineStyle.SINGLE);
		timesBoldUnderline = new WritableCellFormat(times10ptBoldUnderline);
		// Lets automatically wrap the cells
		timesBoldUnderline.setWrap(true);

		CellView cv = new CellView();
		cv.setFormat(times);
		cv.setFormat(timesBoldUnderline);
		cv.setAutosize(true);

		// Write a few headers
		addCaption(sheet, 0, 0, "STT");
		int i = 1;
		for (String column : columns) {
			addCaption(sheet, i, 0, column);
			i++;
		}

	}

	@SuppressWarnings("unchecked")
	private void createContentColumn(WritableSheet sheet, Collection<? extends Object> students, Attendance attendance)
			throws WriteException, RowsExceededException {
		ArrayList<Student> stu = null;
		if(students instanceof ArrayList<?>){
			ArrayList<?> list = (ArrayList<?>)students;
			if( list.size() > 0 && list.get(0) instanceof Student){
				stu = (ArrayList<Student>)list;
			}
		}
		if(stu == null || stu.size() <= 0){
			return;
		}
		int row = 1;

		for (int i = 0; i< students.size() ; i++) {
			if(attendance.get(stu.get(i).getMaSV()) != 0){
				addLabel(sheet, column, row, "X");
			}

			row++;
		}
		column++;

	}

	private void createContentRow(WritableSheet sheet,
			Collection<? extends Object> outputData) throws WriteException,
			RowsExceededException {

		int row = 1;
		for (Object object : outputData) {

			Field[] attributes = object.getClass().getDeclaredFields();
			
			column = 0;
			addNumber(sheet, column, row, row);
			column++;
			for (Field field : attributes) {
				try {
					field.setAccessible(true);
					// Dynamically get Attribute Value
					if (field.getType().getName().equals("int")) {
						addNumber(sheet, column, row,
								Integer.parseInt(field.get(object) + ""));
					} else if (field.getType().getName()
							.equals("java.lang.String")) {
						addLabel(sheet, column, row, field.get(object) + "");
					} else {
						addLabel(sheet, column, row, field.get(object) + "");
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				column++;
			}
			row++;
		}
		// // Load all fields in the class (private included)
		// // Write a few number
		// for (int i = 1; i < 10; i++) {
		// // First column
		// addLabel(sheet, 0, i, "10000");
		// // Second column
		// addLabel(sheet, 1, i, "VanAnh");
		// //Thirth column
		// addNumber(sheet, 2, i, i);
		// }
		// // Lets calculate the sum of it
		// // StringBuffer buf = new StringBuffer();
		// // buf.append("SUM(C2:C10)");
		// // Formula f = new Formula(2, 10, buf.toString());
		// // sheet.addCell(f);
	}

	private void addCaption(WritableSheet sheet, int column, int row, String s)
			throws RowsExceededException, WriteException {
		Label label;
		label = new Label(column, row, s, timesBoldUnderline);
		sheet.addCell(label);
	}

	private void addNumber(WritableSheet sheet, int column, int row,
			Integer integer) throws WriteException, RowsExceededException {
		Number number;
		number = new Number(column, row, integer, times);
		sheet.addCell(number);
	}

	private void addLabel(WritableSheet sheet, int column, int row, String s)
			throws WriteException, RowsExceededException {
		Label label;
		label = new Label(column, row, s, times);
		sheet.addCell(label);
	}

	public interface OnFinishedWrittingListener {
		public void OnFinished();
	}
}
